home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 1
/
Cream of the Crop 1.iso
/
PRINTER
/
JPSRC11.ARJ
/
JETRST.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-08-04
|
29KB
|
1,010 lines
/*
* JET PAK - HP DeskJet and LaserJet series printer utilities
*
* JETRST program - restore soft font file from symbolic dump
*
* Version 1.1 (Public Domain)
*/
/* system include files */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* application include files */
#include "patchlev.h"
#include "jetfont.h"
#include "jetutil.h"
#include "jetbmp.h"
/*
* MODULE GLOBAL DATA
*/
/* scratch area for decompressed DJ bitmap */
static char scratch[BITMAP_SIZE_MAX];
/* token read from file */
static char token[1000];
/* input line being read (used for error reporting only) */
static int line;
/* font command being processed */
static FONT_COMMAND fc;
/* get_token() can return these values (also EOF) */
#define TOKEN_KEYWORD 1
#define TOKEN_DATA 2
/* unget_token() stores the previous result here */
static int unget_value;
/*
* LOCAL FUNCTIONS
*/
static void usage_wrong()
{
/*
* Print usage message and exit.
*/
fprintf(stderr, USAGE_HEADER);
fprintf(stderr, "Usage: JETRST [-h] dumpfile [dumpfile...]\n\n");
fprintf(stderr, "Restore soft font files from symbolic listings\n\n");
fprintf(stderr, " -h print this usage information\n");
fprintf(stderr, " dumpfile dump file name\n");
exit(1);
}
#define STATE_WAITING 0
#define STATE_INTOKEN 1
#define STATE_INSTRING 2
#define STATE_EXIT 3
static int get_token(infp)
FILE *infp;
{
/*
* Read the next token from the dump file.
*
* Tokens are separated by white space (space, tab, new line, and
* form feed); they may also be terminated by special characters
* such as quote ("), comment indicator or keyword indicator.
*
* Data may be enclosed in quotes in which case white space may
* legimiately be included as part of the data; within quotes,
* \ is used to escape '"' and '\'.
*
* This routine returns EOF at end of file, TOKEN_KEYWORD if it
* finds a token beginning with the keyword indicator, otherwise
* TOKEN_DATA is returned.
*/
int c, result = EOF, i = 0, state = STATE_WAITING;
int newline_warning = FALSE, token_warning = FALSE;
/* check for pushed back token */
if (unget_value != 0)
{
result = unget_value;
unget_value = 0;
}
else
{
do
{
switch(c = getc(infp))
{
case EOF:
ungetc(c, infp);
token[i] = '\0';
state = STATE_EXIT;
break;
case '\n':
case '\f':
case ' ':
case '\t':
if (state == STATE_INTOKEN)
{
/* white space terminates token */
ungetc(c, infp);
token[i] = '\0';
state = STATE_EXIT;
/* don't increment line count here, because the
/n is pushed back and re-read! */
}
else if (state == STATE_INSTRING)
{
/* give warning first time newline is found in a
string as this is probably an error */
if (c == '\n')
{
if (!newline_warning)
{
newline_warning = TRUE;
fprintf(stderr, WARNING_STRING_NL,
os_dir, os_file, line);
}
line++; /* line completed */
}
/* space and tab allowed in string */
token[i++] = (char)c;
}
else /* state == STATE_WAITING */
{
if (c == '\n')
line++; /* line completed */
}
break;
case COMMENT_CHARACTER:
if (state == STATE_WAITING)
{
/* consume comment */
while ((c = getc(infp)) != EOF && c != '\n')
;
ungetc(c, infp);
if (c == EOF)
{
token[i] = '\0';
state = STATE_EXIT;
}
}
else if (state == STATE_INSTRING)
{
/* comment character is just part of the string */
token[i++] = (char)c;
}
else /* state == STATE_INTOKEN */
{
/* comment character terminates token */
ungetc(c, infp);
token[i] = '\0';
state = STATE_EXIT;
}
break;
case KEYWORD_CHARACTER:
if (state == STATE_WAITING)
{
/* start of keyword token*/
result = TOKEN_KEYWORD;
state = STATE_INTOKEN;
}
/* keyword character is just part of the token */
token[i++] = (char)c;
break;
case '"':
if (state == STATE_WAITING)
{
/* start of string data */
result = TOKEN_DATA;
state = STATE_INSTRING;
}
else if (state == STATE_INSTRING)
{
/* end of string data */
token[i] = '\0';
state = STATE_EXIT;
}
else /* state == STATE_INTOKEN */
{
/* quote character terminates a token */
ungetc(c, infp);
token[i] = '\0';
state = STATE_EXIT;
}
break;
case '\\':
if (state == STATE_INSTRING)
{
/* escaped '\' or '"' */
if ((c = getc(infp)) == EOF)
{
ungetc(c, infp);
token[i] = '\0';
state = STATE_EXIT;
break;
}
}
/* !! INTENTIONAL DROP-THROUGH !! */
default:
if (state == STATE_WAITING)
{
/* start of regular data */
result = TOKEN_DATA;
state = STATE_INTOKEN;
}
/* regular character as part of token or string */
token[i++] = (char)c;
break;
}
/* check for token overflow */
if (i == sizeof(token))
{
i--;
if (!token_warning)
{
token_warning = TRUE;
fprintf(stderr, WARNING_TOKEN_OVERFLOW,
os_dir, os_file, line-1);
}
}
} while (state != STATE_EXIT);
}
return(result);
}
static void unget_token(result)
int result;
{
/*
* Push back token so it will be returned by the next
* get_token(). Only one level of unget_token() is supported.
*/
unget_value = result;
}
static int get_unsigned_byte(infp, p)
FILE *infp;
UNSIGNEDBYTE *p;
{
/*
* Read a token to be interpreted as UNSIGNEDBYTE; store the
* result in *p, if data is read successfully.
*/
int result;
UNSIGNEDINT value;
if ((result = get_token(infp)) == TOKEN_DATA)
{
sscanf(token, "%hu", &value);
*p = (UNSIGNEDBYTE)value;
}
return(result);
}
static int get_signed_byte(infp, p)
FILE *infp;
SIGNEDBYTE *p;
{
/*
* Read a token to be interpreted as SIGNEDBYTE; store the
* result in *p, if data is read successfully.
*/
int result;
SIGNEDINT value;
if ((result = get_token(infp)) == TOKEN_DATA)
{
sscanf(token, "%hd", &value);
*p = (SIGNEDBYTE)value;
}
return(result);
}
static int get_unsigned_int(infp, p)
FILE *infp;
UNSIGNEDINT *p;
{
/*
* Read a token to be interpreted as UNSIGNEDINT; store the
* result in *p, if data is read successfully.
*/
int result;
if ((result = get_token(infp)) == TOKEN_DATA)
sscanf(token, "%hu", p);
return(result);
}
static int get_signed_int(infp, p)
FILE *infp;
SIGNEDINT *p;
{
/*
* Read a token to be interpreted as SIGNEDINT; store the
* result in *p, if data is read successfully.
*/
int result;
if ((result = get_token(infp)) == TOKEN_DATA)
sscanf(token, "%hd", p);
return(result);
}
static int bitmap_data_restore(infp, bp, cw, ch, dsize)
FILE *infp;
UNSIGNEDBYTE *bp;
UNSIGNEDINT cw, ch;
UNSIGNEDINT dsize;
{
/*
* Restore the data in the bitmap record, returning the number of
* bytes read if successful.
*/
int result;
register UNSIGNEDBYTE *bp2 = bp;
register UNSIGNEDINT pmask;
UNSIGNEDINT x, len;
/* check sufficient space is available */
if ((((cw + 7)/8)*ch) > dsize)
return(ERROR);
while (ch-- > 0)
{
/* read a row - tolerate (ie clear) missing rows at bottom of bitmap */
if ((result = get_token(infp)) == TOKEN_DATA)
{
len = strlen(token);
}
else
{
unget_token(result);
len = 0;
}
*bp2 = 0;
for (x = 0, pmask = 0x80; x < cw; x++, pmask >>= 1)
{
if (pmask == 0)
{
pmask = 0x80;
bp2++;
*bp2 = 0;
}
/* tolerate (ie clear) missing bits at end of row */
if ((x < len) && (token[x] == '@'))
*bp2 |= pmask;
}
bp2++;
}
return((int)(bp2 - bp));
}
static int bitmap_restore(infp, outfp)
FILE *infp;
FILE *outfp;
{
/*
* Restore a bitmap record
*/
int result;
/* read the bitmap data */
switch(fc.data.character.format)
{
default:
case LJCHARFORMAT:
if ((result = bitmap_data_restore(infp,
fc.data.character.data.ljchar.bitmap,
fc.data.character.data.ljchar.character_width,
fc.data.character.data.ljchar.character_height,
sizeof(fc.data.character.data.ljchar.bitmap))) == ERROR)
{
fprintf(stderr, ERROR_BITMAP_TOO_BIG, os_dir, os_file);
return(ERROR);
}
fc.number += result;
break;
case DJCHARFORMAT:
case DJPCHARFORMAT:
case DJ500CHARFORMAT:
if ((result = bitmap_data_restore(infp,
scratch,
fc.data.character.data.djchar.character_width,
PASS_HEIGHT,
sizeof(scratch))) == ERROR)
{
fprintf(stderr, ERROR_BITMAP_TOO_BIG, os_dir, os_file);
return(ERROR);
}
if ((result = bitmap_compress(scratch,
fc.data.character.data.djchar.character_width,
PASS_HEIGHT,
fc.data.character.data.djchar.bitmap,
sizeof(fc.data.character.data.djchar.bitmap))) == ERROR)
{
fprintf(stderr, ERROR_BITMAP_TOO_BIG, os_dir, os_file);
return(ERROR);
}
fc.number += result;
break;
}
/* write out the character descriptor and associated bitmap */
if (font_command_write(outfp, &fc) == ERROR)
{
fprintf(stderr, ERROR_FILE_WRITE_FAILED, os_dir, os_file);
return(ERROR);
}
return(OK);
}
static int header_data_restore(infp)
FILE *infp;
{
/*
* Restore the data in the header record
*/
FONT_DESCRIPTOR *fdp = &fc.data.font;
int result;
fc.command_type = FDC;
if ((result = get_unsigned_int(infp, &fdp->size)) != TOKEN_DATA)
return(result);
if ((result = get_unsigned_byte(infp, &fdp->header_format)) != TOKEN_DATA)
return(result);
if ((result = get_unsigned_byte(infp, &fdp->type)) != TOKEN_DATA)
return(result);
if ((result = get_unsigned_int(infp, &fdp->reserved1)) != TOKEN_DATA)
return(result);
if ((result = get_unsigned_int(infp, &fdp->baseline_distance)) != TOKEN_DATA)
return(result);
if ((result = get_unsigned_int(infp, &fdp->cell_width)) != TOKEN_DATA)
return(result);
if ((result = get_unsigned_int(infp, &fdp->cell_height)) != TOKEN_DATA)
return(result);
if ((result = get_unsigned_byte(infp, &fdp->orientation)) != TOKEN_DATA)
return(result);
if ((result = get_unsigned_byte(infp, &fdp->spacing)) != TOKEN_DATA)
return(result);
if ((result = get_unsigned_int(infp, &fdp->symbol_set)) != TOKEN_DATA)
return(result);
if ((result = get_unsigned_int(infp, &fdp->pitch)) != TOKEN_DATA)
return(result);
if ((result = get_unsigned_int(infp, &fdp->height)) != TOKEN_DATA)
return(result);
if ((result = get_unsigned_int(infp, &fdp->x_height)) != TOKEN_DATA)
return(result);
if ((result = get_signed_byte(infp, &fdp->width_type)) != TOKEN_DATA)
return(result);
if ((result = get_unsigned_int(infp, &fdp->style)) != TOKEN_DATA)
return(result);
if ((result = get_signed_byte(infp, &fdp->stroke_weight)) != TOKEN_DATA)
return(result);
if ((result = get_unsigned_int(infp, &fdp->typeface)) != TOKEN_DATA)
return(result);
if ((result = get_unsigned_byte(infp, &fdp->slant)) != TOKEN_DATA)
return(result);
if ((result = get_unsigned_byte(infp, &fdp->serif_style)) != TOKEN_DATA)
return(result);
if ((result = get_unsigned_byte(infp, &fdp->quality)) != TOKEN_DATA)
return(result);
if ((result = get_signed_byte(infp, &fdp->placement)) != TOKEN_DATA)
return(result);
if ((result = get_signed_byte(infp, &fdp->underline_distance)) != TOKEN_DATA)
return(result);
if ((result = get_unsigned_byte(infp, &fdp->underline_height)) != TOKEN_DATA)
return(result);
if ((result = get_unsigned_int(infp, &fdp->text_height)) != TOKEN_DATA)
return(result);
if ((result = get_unsigned_int(infp, &fdp->text_width)) != TOKEN_DATA)
return(result);
if ((result = get_unsigned_int(infp, &fdp->first_code)) != TOKEN_DATA)
return(result);
if ((result = get_unsigned_int(infp, &fdp->last_code)) != TOKEN_DATA)
return(result);
if ((result = get_unsigned_byte(infp, &fdp->pitch_extended)) != TOKEN_DATA)
return(result);
if ((result = get_unsigned_byte(infp, &fdp->height_extended)) != TOKEN_DATA)
return(result);
if ((result = get_unsigned_int(infp, &fdp->reserved2)) != TOKEN_DATA)
return(result);
if ((result = get_unsigned_int(infp, &fdp->font_number_top)) != TOKEN_DATA)
return(result);
if ((result = get_unsigned_int(infp, &fdp->font_number_bot)) != TOKEN_DATA)
return(result);
if ((result = get_unsigned_int(infp, &fdp->h_pixel_resolution)) != TOKEN_DATA)
return(result);
if ((result = get_unsigned_int(infp, &fdp->v_pixel_resolution)) != TOKEN_DATA)
return(result);
if ((result = get_signed_byte(infp, &fdp->tdu_distance)) != TOKEN_DATA)
return(result);
if ((result = get_unsigned_byte(infp, &fdp->tdu_height)) != TOKEN_DATA)
return(result);
if ((result = get_signed_byte(infp, &fdp->bdu_distance)) != TOKEN_DATA)
return(result);
if ((result = get_unsigned_byte(infp, &fdp->bdu_height)) != TOKEN_DATA)
return(result);
if ((result = get_unsigned_int(infp, &fdp->specific_size)) != TOKEN_DATA)
return(result);
if ((result = get_unsigned_int(infp, &fdp->data_size)) != TOKEN_DATA)
return(result);
if ((result = get_unsigned_byte(infp, &fdp->unidirection)) != TOKEN_DATA)
return(result);
if ((result = get_unsigned_byte(infp, &fdp->compressed)) != TOKEN_DATA)
return(result);
if ((result = get_unsigned_byte(infp, &fdp->hold_time_factor)) != TOKEN_DATA)
return(result);
if ((result = get_unsigned_byte(infp, &fdp->no_half_pitch)) != TOKEN_DATA)
return(result);
if ((result = get_unsigned_byte(infp, &fdp->no_double_pitch)) != TOKEN_DATA)
return(result);
if ((result = get_unsigned_byte(infp, &fdp->no_half_height)) != TOKEN_DATA)
return(result);
if ((result = get_unsigned_byte(infp, &fdp->no_bold)) != TOKEN_DATA)
return(result);
if ((result = get_unsigned_byte(infp, &fdp->no_draft)) != TOKEN_DATA)
return(result);
if ((result = get_unsigned_byte(infp, &fdp->bold_method)) != TOKEN_DATA)
return(result);
if ((result = get_unsigned_byte(infp, &fdp->reserved3)) != TOKEN_DATA)
return(result);
if ((result = get_unsigned_int(infp, &fdp->baseline_offset_2)) != TOKEN_DATA)
return(result);
if ((result = get_unsigned_int(infp, &fdp->baseline_offset_3)) != TOKEN_DATA)
return(result);
if ((result = get_unsigned_int(infp, &fdp->baseline_offset_4)) != TOKEN_DATA)
return(result);
return(get_token(infp));
}
static int header_restore(infp, outfp)
FILE *infp;
FILE *outfp;
{
/*
* Restore the font descriptor records
*/
int result;
/* check for header keyword */
if ( ((result = get_token(infp)) != TOKEN_KEYWORD)
|| (strcmp(token, KEYWORD_HEADER) != 0) )
{
fprintf(stderr, ERROR_KEYWORD_MISSING, os_dir, os_file, line);
unget_token(result);
return(ERROR);
}
/* get header data and check for name keyword */
if ( ((result = header_data_restore(infp)) != TOKEN_KEYWORD)
|| (strcmp(token, KEYWORD_NAME) != 0) )
{
fprintf(stderr, ERROR_KEYWORD_MISSING, os_dir, os_file, line);
unget_token(result);
return(ERROR);
}
/* get name data */
if ((result = get_token(infp)) != TOKEN_DATA)
{
fprintf(stderr, ERROR_DATA_MISSING, os_dir, os_file, line);
unget_token(result);
return(ERROR);
}
strncpy(fc.data.font.name, token, sizeof(fc.data.font.name));
if (fc.data.font.header_format == DJ500FONTFORMAT)
{
/* also copy the name extension for DJ500 only */
strncpy(fc.data.font.name_extension, token+sizeof(fc.data.font.name),
sizeof(fc.data.font.name_extension));
}
/* fix up the descriptor size and number */
switch(fc.data.font.header_format)
{
default:
fprintf(stderr, WARNING_BAD_FONT_FORMAT,
os_dir, os_file, fc.data.font.header_format);
/* !! INTENTIONAL DROP-THROUGH !! */
case LJFONTFORMAT:
fc.data.font.size = LJFDSIZE;
fc.number = LJFDSIZE+LJSSIZE;
break;
case DJFONTFORMAT:
case DJPFONTFORMAT:
fc.data.font.size = DJFDSIZE;
fc.number = DJFDSIZE+DJSSIZE;
break;
case DJ500FONTFORMAT:
fc.data.font.size = DJ500FDSIZE;
fc.number = DJ500FDSIZE+DJ500SSIZE;
break;
}
/* check for comment keyword */
if ( ((result = get_token(infp)) != TOKEN_KEYWORD)
|| (strcmp(token, KEYWORD_COMMENT) != 0) )
{
fprintf(stderr, ERROR_KEYWORD_MISSING, os_dir, os_file, line);
unget_token(result);
return(ERROR);
}
/* get comment data */
if ((result = get_token(infp)) != TOKEN_DATA)
{
fprintf(stderr, ERROR_DATA_MISSING, os_dir, os_file, line);
unget_token(result);
return(ERROR);
}
strncpy(fc.data.font.comment, token, COMMENT_SIZE_MAX-1);
fc.data.font.comment[COMMENT_SIZE_MAX-1] = '\0'; /* failsafe */
fc.number += strlen(fc.data.font.comment);
/* write out the header */
if (font_command_write(outfp, &fc) == ERROR)
{
fprintf(stderr, ERROR_FILE_WRITE_FAILED, os_dir, os_file);
return(ERROR);
}
return(OK);
}
static int character_data_restore(infp)
FILE *infp;
{
/*
* Restore the data in the character descriptor
*/
struct ljchar_struct *ljcp;
struct djchar_struct *djcp;
int result;
fc.number = 0;
fc.command_type = CDC;
if ((result = get_unsigned_byte(infp, &fc.data.character.format)) != TOKEN_DATA)
return(result);
fc.number += 1;
if ((result = get_unsigned_byte(infp, &fc.data.character.continuation)) != TOKEN_DATA)
return(result);
fc.number += 1;
switch(fc.data.character.format)
{
default:
fprintf(stderr, WARNING_BAD_CHAR_FORMAT,
os_dir, os_file, fc.data.character.format);
/* !! INTENTIONAL DROP-THROUGH !! */
case LJCHARFORMAT:
ljcp = &fc.data.character.data.ljchar;
if ((result = get_unsigned_byte(infp, &ljcp->descriptor_size)) != TOKEN_DATA)
return(result);
fc.number += 1;
if ((result = get_unsigned_byte(infp, &ljcp->class)) != TOKEN_DATA)
return(result);
fc.number += 1;
if ((result = get_unsigned_byte(infp, &ljcp->orientation)) != TOKEN_DATA)
return(result);
fc.number += 1;
if ((result = get_unsigned_byte(infp, &ljcp->reserved)) != TOKEN_DATA)
return(result);
fc.number += 1;
if ((result = get_signed_int(infp, &ljcp->left_offset)) != TOKEN_DATA)
return(result);
fc.number += 2;
if ((result = get_signed_int(infp, &ljcp->top_offset)) != TOKEN_DATA)
return(result);
fc.number += 2;
if ((result = get_unsigned_int(infp, &ljcp->character_width)) != TOKEN_DATA)
return(result);
fc.number += 2;
if ((result = get_unsigned_int(infp, &ljcp->character_height)) != TOKEN_DATA)
return(result);
fc.number += 2;
if ((result = get_signed_int(infp, &ljcp->delta_x)) != TOKEN_DATA)
return(result);
fc.number += 2;
break;
case DJCHARFORMAT:
case DJPCHARFORMAT:
case DJ500CHARFORMAT:
djcp = &fc.data.character.data.djchar;
if ((result = get_unsigned_byte(infp, &djcp->descriptor_size)) != TOKEN_DATA)
return(result);
fc.number += 1;
if ((result = get_unsigned_byte(infp, &djcp->char_type)) != TOKEN_DATA)
return(result);
fc.number += 1;
if ((result = get_unsigned_byte(infp, &djcp->character_width)) != TOKEN_DATA)
return(result);
fc.number += 1;
if ((result = get_unsigned_byte(infp, &djcp->comp_width)) != TOKEN_DATA)
return(result);
fc.number += 1;
if ((result = get_signed_byte(infp, &djcp->left_offset)) != TOKEN_DATA)
return(result);
fc.number += 1;
if ((result = get_signed_byte(infp, &djcp->right_offset)) != TOKEN_DATA)
return(result);
fc.number += 1;
break;
}
return(get_token(infp));
}
static int character_restore(infp, outfp)
FILE *infp;
FILE *outfp;
{
/*
* Restore a character descriptor record
*/
int result;
/* get and output the character code first */
if ((result = get_token(infp)) != TOKEN_DATA)
{
fprintf(stderr, ERROR_DATA_MISSING, os_dir, os_file, line);
unget_token(result);
return(ERROR);
}
fc.command_type = CCC;
sscanf(token, "%d", &fc.number);
/* write out the character code escape sequence */
if (font_command_write(outfp, &fc) == ERROR)
{
fprintf(stderr, ERROR_FILE_WRITE_FAILED, os_dir, os_file);
return(ERROR);
}
/* get character data and check for bitmap keyword */
if ( ((result = character_data_restore(infp)) != TOKEN_KEYWORD)
|| (strcmp(token, KEYWORD_BITMAP) != 0) )
{
fprintf(stderr, ERROR_KEYWORD_MISSING, os_dir, os_file, line);
unget_token(result);
return(ERROR);
}
unget_token(result);
return(OK);
}
static int file_restore(infp, outfp)
FILE *infp;
FILE *outfp;
{
int result;
/* read the header information first */
if (header_restore(infp, outfp) == ERROR)
return(ERROR);
while ( ((result = get_token(infp)) == TOKEN_KEYWORD)
&& (strcmp(token, KEYWORD_CHAR) == 0) )
{
/* restore the character descriptor header */
if (character_restore(infp, outfp) == ERROR)
return(ERROR);
/* must get bitmap data next */
if ( ((result = get_token(infp)) != TOKEN_KEYWORD)
|| (strcmp(token, KEYWORD_BITMAP) != 0) )
{
fprintf(stderr, ERROR_KEYWORD_MISSING, os_dir, os_file, line);
unget_token(result);
return(ERROR);
}
/* restore character descriptor bitmap data */
if (bitmap_restore(infp, outfp) == ERROR)
return(ERROR);
}
/* check loop was exited either at EOF or on reading start of next
dumped file */
if ( (result == TOKEN_KEYWORD && strcmp(token, KEYWORD_FILE) != 0)
|| (result == TOKEN_DATA) )
{
fprintf(stderr, ERROR_KEYWORD_MISSING, os_dir, os_file, line);
unget_token(result);
return(ERROR);
}
unget_token(result); /* because next token or EOF was read */
return(OK);
}
static void jetrst()
{
char inpath[OS_PATH_LEN], outpath[OS_PATH_LEN];
FILE *infp, *outfp;
int result, file_found = FALSE;
/* build the input and output file paths */
strcpy(inpath, os_dir);
strcat(inpath, os_file);
if (!(infp = fopen(inpath, "r")))
{
fprintf(stderr, ERROR_OPEN_READ_FAILED, os_dir, os_file);
return;
}
/* initialise per input file data */
line = 1;
unget_value = 0;
/* skip up to file keyword or EOF */
while ((result = get_token(infp)) != EOF)
{
if ( (result == TOKEN_KEYWORD)
&& (strcmp(token, KEYWORD_FILE) == 0) )
{
file_found = TRUE;
/* read file name */
if ((result = get_token(infp)) != TOKEN_DATA)
{
fprintf(stderr, ERROR_DATA_MISSING, os_dir, os_file, line);
unget_token(result);
continue;
}
strncpy(outpath, token, OS_PATH_LEN-1);
outpath[OS_PATH_LEN-1] = '\0'; /* fail-safe NULL termination */
/* rudimentary check for input overwriting output */
if (strcmp(inpath, outpath) == 0)
{
fprintf(stderr, ERROR_OVERWRITE, os_dir, os_file);
continue;
}
if (!(outfp = fopen(outpath, "wb")))
{
fprintf(stderr, ERROR_OPEN_WRITE_FAILED, os_dir, os_file, outpath);
continue;
}
if (file_restore(infp, outfp) == OK)
fprintf(stderr, OK_JETRST, os_dir, os_file, outpath);
fclose(outfp);
}
}
if (!file_found)
fprintf(stderr, ERROR_FILE_READ_FAILED, os_dir, os_file);
fclose(infp);
}
/*
* EXTERNAL FUNCTION
*/
int main(argc, argv)
int argc;
char *argv[];
{
char c;
/* stop getopt() printing errors */
opterr = FALSE;
while ((c = getopt(argc, argv, "h")) != EOF)
{
switch (c)
{
case 'h':
case '?':
/* help required, or invalid option specified */
usage_wrong();
}
}
/* must specify at least one file */
if (optind >= argc)
usage_wrong();
/* process file arguments */
if (os_findfiles((argc - optind), &argv[optind]) == ERROR)
fprintf(stderr, ERROR_OUT_OF_HEAP);
while (os_getfile() != EOF)
jetrst();
return(0);
}